package com.ssy.lingxi.search.serviceImpl;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.common.model.vo.PageVO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.component.redis.service.IRedisStringUtils;
import com.ssy.lingxi.search.api.model.request.CommoditySearchRequest;
import com.ssy.lingxi.search.api.model.response.BrandResponse;
import com.ssy.lingxi.search.api.model.response.CategoryResponse;
import com.ssy.lingxi.search.common.utils.ListPageUtil;
import com.ssy.lingxi.search.service.ITemplateChannelService;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 商品实现类
 * @author jw.chen
 * @version 2.0.0
 * @date 2020/6/22
 */
@Service
public class TemplateChannelServiceImpl implements ITemplateChannelService {

    @Resource
    private RestHighLevelClient restHighLevelClient;

    @Resource
    private IRedisStringUtils redisStringUtils;

    /**
     * 查询一级分类
     * @return
     */
    @Override
    public List<CategoryResponse> getFirstCategoryList(Long shopId, Long memberId) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        //定义参数变量
        String esField;
        String redisKey;
        // 会员
        if(memberId != null && memberId > 0){
            esField = "customerCategory.fullId.keyword";
            redisKey = Constants.REDIS_KEY_CUSTOMER_CATEGORY;
        }else{
            esField = "customerCategory.category.fullId.keyword";
            redisKey = Constants.REDIS_KEY_CATEGORY;
        }

        // 按商城环境
        if(shopId != null && shopId > 0){
            queryBuilder.must(QueryBuilders.matchQuery("memberList.shopList.shopId", shopId));
        }
//        if(type != null && type > 0){
//            if(type == ShopTypeEnum.Channel.getCode() || type == ShopTypeEnum.Channel_Score.getCode() || type == ShopTypeEnum.Channel_Self.getCode() || type == ShopTypeEnum.Channel_Score.getCode()){
//                queryBuilder.must(QueryBuilders.matchQuery("memberList.shopList.type", type));
//            }
//        }
//        if(environment != null && environment > 0){
//            if(type == ShopTypeEnum.Channel.getCode() || type == ShopTypeEnum.Channel_Score.getCode() || type == ShopTypeEnum.Channel_Self.getCode() || type == ShopTypeEnum.Channel_Score.getCode()){
//                queryBuilder.must(QueryBuilders.matchQuery("memberList.shopList.environment", environment));
//            }
//        }

        //供应商
        if(memberId != null && memberId > 0){
            queryBuilder.must(QueryBuilders.matchQuery("memberList.channelMemberId", memberId));
        }

        //构建查询条件
        SearchRequest search = new SearchRequest(Constants.ES_COMMODITY_INDEX);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.size(0);
        searchSourceBuilder.query(queryBuilder);
        //分组
        TermsAggregationBuilder aggregationCategoryId = AggregationBuilders.terms("group_categoryId").field(esField).size(1200000);
        searchSourceBuilder.aggregation(aggregationCategoryId);
        search.source(searchSourceBuilder);
        try{
            Set<Long> firstCategory = new HashSet<>();
            //搜索
            SearchResponse searchResponse = restHighLevelClient.search(search, RequestOptions.DEFAULT);
            Aggregations aggregations = searchResponse.getAggregations();
            if(aggregations != null){
                Terms brandTerms = aggregations.get("group_categoryId");
                List<? extends Terms.Bucket> brandBuckets = brandTerms.getBuckets();
                if(brandBuckets != null){
                    brandBuckets.forEach(bucket -> {
                        //将品类进行组装
                        String fullId = String.valueOf(bucket.getKey());
                        if(fullId.contains(Constants.SPLIT_STR_FULL_ID)){
                            String[] split = fullId.split(Constants.TRANSFER_STR + Constants.SPLIT_STR_FULL_ID);
                            firstCategory.add(Long.valueOf(split[0]));
                        }else{
                            firstCategory.add(Long.valueOf(fullId));
                        }
                    });
                }
            }
            if(!firstCategory.isEmpty()){
                Map<String, String> categoryMap = redisStringUtils.hGetAll(redisKey, Constants.REDIS_PRODUCT_INDEX);
                //遍历品类信息
                return firstCategory.stream().map(categoryId -> {
                    String category = categoryMap.get(String.valueOf(categoryId));
                    if(StringUtils.isNotEmpty(category)){
                        JSONObject jsonObject = JSONUtil.parseObj(category);
                        CategoryResponse categoryResponse = new CategoryResponse();
                        categoryResponse.setId(categoryId);
                        categoryResponse.setName(jsonObject.getStr("name"));
                        return categoryResponse;
                    }else{
                        return null;
                    }
                }).filter(Objects::nonNull).collect(Collectors.toList());
            }
            return null;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 查询品牌列表
     * @param pageVO
     * @param searchRequest
     * @return
     */
    @Override
    public PageData<BrandResponse> searchBrandList(PageVO pageVO, CommoditySearchRequest searchRequest){
        List<BrandResponse> brandList = new ArrayList<>();
        // 查询条件
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        // 获取查询参数
        Long memberId = searchRequest.getMemberId();
        Long memberRoleId = searchRequest.getMemberRoleId();
        String name = searchRequest.getName();
        Long categoryId = searchRequest.getCategoryId();
        Long customerCategoryId = searchRequest.getCustomerCategoryId();
        List<Long> idInList = searchRequest.getIdInList();
        List<Long> idNotInList = searchRequest.getIdNotInList();
        Long shopId = searchRequest.getShopId();
//        Integer type = searchRequest.getType();
//        Integer environment = searchRequest.getEnvironment();

        // id搜索
        if(idInList != null && !idInList.isEmpty()){
            queryBuilder.must(QueryBuilders.termsQuery("brand.id", idInList));
        }
        if(idNotInList != null && !idNotInList.isEmpty()){
            queryBuilder.mustNot(QueryBuilders.termsQuery("brand.id", idNotInList));
        }

//        // 拼接会员搜索
//        if(memberId != null && memberId > 0){
//            queryBuilder.must(QueryBuilders.matchQuery("memberId", memberId));
//        }
//
//        // 拼接会员搜索
//        if(memberRoleId != null && memberRoleId > 0){
//            queryBuilder.must(QueryBuilders.matchQuery("memberRoleId", memberRoleId));
//        }

        // 拼接关键字搜索(品牌名称)
        if(StringUtils.isNotEmpty(name)){
            MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(searchRequest.getName(), "brand.name");
            queryBuilder.must(multiMatchQueryBuilder);
        }

        // 拼接分类搜索
        String categoryKey;
        if(customerCategoryId != null && customerCategoryId > 0){
            categoryKey = "customerCategory.fullId:*";
            queryBuilder.must(QueryBuilders.queryStringQuery(categoryKey + String.format(Constants.CATEGORY_FULL_ID_NUM, customerCategoryId) + "*"));
        }
        if(categoryId != null && categoryId > 0){
            categoryKey = "customerCategory.category.fullId:*";
            queryBuilder.must(QueryBuilders.queryStringQuery(categoryKey + String.format(Constants.CATEGORY_FULL_ID_NUM, categoryId) + "*"));
        }

        // 按商城环境
        queryBuilder.must(QueryBuilders.matchQuery("memberList.shopList.shopId", shopId));
//        if(type != null && type > 0){
//            if(type == ShopTypeEnum.Channel.getCode() || type == ShopTypeEnum.Channel_Score.getCode() || type == ShopTypeEnum.Channel_Self.getCode() || type == ShopTypeEnum.Channel_Score.getCode()){
//                queryBuilder.must(QueryBuilders.matchQuery("memberList.shopList.type", type));
//            }
//        }
//        if(environment != null && environment > 0){
//            if(type == ShopTypeEnum.Channel.getCode() || type == ShopTypeEnum.Channel_Score.getCode() || type == ShopTypeEnum.Channel_Self.getCode() || type == ShopTypeEnum.Channel_Score.getCode()){
//                queryBuilder.must(QueryBuilders.matchQuery("memberList.shopList.environment", environment));
//            }
//        }

        //供应商
        if(memberId != null && memberId > 0){
            queryBuilder.must(QueryBuilders.matchQuery("memberList.channelMemberId", memberId));
        }

//        // 按商城环境
//        if(type != null && type > 0){
//            queryBuilder.must(QueryBuilders.matchQuery("commodityShopList.type", type));
//        }
//        if(environment != null && environment > 0){
//            queryBuilder.must(QueryBuilders.matchQuery("commodityShopList.environment", environment));
//        }

        //构建查询条件
        SearchRequest search = new SearchRequest(Constants.ES_COMMODITY_INDEX);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.size(0);
        searchSourceBuilder.query(queryBuilder);
        //分组
        TermsAggregationBuilder aggregationBrandId = AggregationBuilders.terms("group_brandId").field("brand.id").size(1200000)
                .subAggregation(AggregationBuilders.terms("group_brandName").field("brand.name.keyword").subAggregation(AggregationBuilders.terms("group_brandLogoUrl").field("brand.logoUrl.keyword")));
        searchSourceBuilder.aggregation(aggregationBrandId);
        search.source(searchSourceBuilder);
        //搜索
        try{
            SearchResponse searchResponse = restHighLevelClient.search(search, RequestOptions.DEFAULT);
            Aggregations aggregations = searchResponse.getAggregations();
            if(aggregations != null){
                Terms brandTerms = aggregations.get("group_brandId");
                List<? extends Terms.Bucket> brandBuckets = brandTerms.getBuckets();
                if(brandBuckets != null){
                    brandBuckets.forEach(bucket -> {
                        Terms brandNameTerms = bucket.getAggregations().get("group_brandName");
                        List<? extends Terms.Bucket> brandNameBuckets = brandNameTerms.getBuckets();
                        if(brandNameBuckets != null){
                            brandNameBuckets.forEach(bucketName -> {
                                Terms brandLogoUrlTerms = bucketName.getAggregations().get("group_brandLogoUrl");
                                List<? extends Terms.Bucket> brandLogoUrlBuckets = brandLogoUrlTerms.getBuckets();
                                brandLogoUrlBuckets.forEach(bucketLogoUrl -> {
                                    BrandResponse brand = new BrandResponse();
                                    brand.setId(Long.valueOf(String.valueOf(bucket.getKey())));
                                    brand.setName(String.valueOf(bucketName.getKey()));
                                    brand.setLogoUrl(String.valueOf(bucketLogoUrl.getKey()));
                                    brandList.add(brand);
                                });
                            });
                        }
                    });
                }
            }
            // 分页
            PageData<BrandResponse> pageData = new PageData<>();
            pageData.setTotalCount((long) brandList.size());
            pageData.setData(ListPageUtil.page(brandList, pageVO.getCurrent(), pageVO.getPageSize()));
            return pageData;
        }catch (Exception e){
            return null;
        }
    }

    /**
     * 查询二级分类
     * @return
     */
    @Override
    public List<CategoryResponse> getSecondCategoryList(Long shopId, Long memberId, Long categoryId){
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        //定义参数变量
        String esName;
        String esField;
        String redisKey;
        // 会员
        if(memberId != null && memberId > 0){
            esName = "customerCategory.fullId";
            esField = "customerCategory.fullId.keyword";
            redisKey = Constants.REDIS_KEY_CUSTOMER_CATEGORY;
        }else{
            esName = "customerCategory.category.fullId";
            esField = "customerCategory.category.fullId.keyword";
            redisKey = Constants.REDIS_KEY_CATEGORY;
        }
        // 拼接平台后台分类搜索
        if(categoryId != null && categoryId > 0){
            queryBuilder.must(QueryBuilders.prefixQuery(esName, String.format(Constants.CATEGORY_FULL_ID_NUM, categoryId)));
        }

        // 按商城环境
        if(shopId != null && shopId > 0){
            queryBuilder.must(QueryBuilders.matchQuery("memberList.shopList.shopId", shopId));
        }
//        if(type != null && type > 0){
//            if(type == ShopTypeEnum.Channel.getCode() || type == ShopTypeEnum.Channel_Score.getCode() || type == ShopTypeEnum.Channel_Self.getCode() || type == ShopTypeEnum.Channel_Score.getCode()){
//                queryBuilder.must(QueryBuilders.matchQuery("memberList.shopList.type", type));
//            }
//        }
//        if(environment != null && environment > 0){
//            if(type == ShopTypeEnum.Channel.getCode() || type == ShopTypeEnum.Channel_Score.getCode() || type == ShopTypeEnum.Channel_Self.getCode() || type == ShopTypeEnum.Channel_Score.getCode()){
//                queryBuilder.must(QueryBuilders.matchQuery("memberList.shopList.environment", environment));
//            }
//        }

        //供应商
        if(memberId != null && memberId > 0){
            queryBuilder.must(QueryBuilders.matchQuery("memberList.channelMemberId", memberId));
        }

        //构建查询条件
        SearchRequest search = new SearchRequest(Constants.ES_COMMODITY_INDEX);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.size(0);
        searchSourceBuilder.query(queryBuilder);
        //分组
        TermsAggregationBuilder aggregationCategoryId = AggregationBuilders.terms("group_categoryId").field(esField).size(1200000);
        searchSourceBuilder.aggregation(aggregationCategoryId);
        search.source(searchSourceBuilder);
        try{
            Set<Long> secondCategory = new HashSet<>();
            //搜索
            SearchResponse searchResponse = restHighLevelClient.search(search, RequestOptions.DEFAULT);
            Aggregations aggregations = searchResponse.getAggregations();
            if(aggregations != null){
                Terms brandTerms = aggregations.get("group_categoryId");
                List<? extends Terms.Bucket> brandBuckets = brandTerms.getBuckets();
                if(brandBuckets != null){
                    brandBuckets.forEach(bucket -> {
                        //将品类进行组装
                        String fullId = String.valueOf(bucket.getKey());
                        if(fullId.contains(Constants.SPLIT_STR_FULL_ID)){
                            String[] split = fullId.split(Constants.TRANSFER_STR + Constants.SPLIT_STR_FULL_ID);
                            secondCategory.add(Long.valueOf(split[1]));
                        }
                    });
                }
            }
            if(!secondCategory.isEmpty()){
                Map<String, String> categoryMap = redisStringUtils.hGetAll(redisKey, Constants.REDIS_PRODUCT_INDEX);
                //遍历品类信息
                return secondCategory.stream().map(secondCategoryId -> {
                    String category = categoryMap.get(String.valueOf(secondCategoryId));
                    JSONObject jsonObject = JSONUtil.parseObj(category);
                    CategoryResponse categoryResponse = new CategoryResponse();
                    categoryResponse.setId(secondCategoryId);
                    categoryResponse.setName(jsonObject.getStr("name"));
                    return categoryResponse;
                }).collect(Collectors.toList());
            }
            return null;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
}